package com.qingzhu.pojo;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.IntStream;
import java.util.stream.Stream;

public class CustomPage<T> {

    // 导航条（存放计算出来所有需要显示的导航按钮，由createNavigatepageNums初始化）
    private List<Integer> firstNavigatepageNums = new ArrayList();
    private List<Integer> lastNavigatepageNums = new ArrayList();
    private List<Integer> navigatepageNums = new ArrayList();
    private int navigateFirstPage;      // 当前页导航条的第一页
    private int navigateLastPage;       // 当前页导航条的最后一页

    /* 分页参数 */
    private int total;      // 总记录数
    private int pageSize;           // 每页的记录数
    private int pageNum;       // 当前页

    private int pages;          // 总页数
    private int currentPrevPageNum;    // 当前页前面需要显示的页数按钮数
    private int currentNextPageNum;    // 当前页后面需要显示的页数按钮数
    private int prePage;        // 上一页
    private int nextPage;       // 下一页

    /* 数据列表 */
    private List<T> list;

    /* 附加功能参数 */
    private int firstNextNum;      // 第一页后面需要显示的页数按钮数
    private int firstNextPage;         // 首页导航条的最后一页
    private int lastPrevNum;       // 最后一页前面需要显示的页数按钮数
    private int lastPrevPage;          // 尾页导航条的第一页


    /* 使用Stream流计算当前分页需要显示的所有页码 */
    private void createNavigatepageNums(){
        // 第一页的页码按钮显示范围
        IntStream firstNextPagNums = IntStream.rangeClosed(1,firstNextPage);
        firstNextPagNums.forEach(f -> firstNavigatepageNums.add(f));
        // 最后一页的页码按钮显示范围
        IntStream lastPrevPageNums = IntStream.rangeClosed(lastPrevPage, pages);
        lastPrevPageNums.forEach(l -> lastNavigatepageNums.add(l));
        // 当前页前面页码按钮的显示范围
        IntStream currentPrevPageNums = IntStream.rangeClosed(pageNum -currentPrevPageNum, pageNum);
        // 初始化当前页导航条的第一页
        navigateFirstPage = Math.max(pageNum -currentPrevPageNum,firstNextPage+1);
        // 当前页后面页码按钮的显示范围
        IntStream currentNextPageNums = IntStream.rangeClosed(pageNum, pageNum +currentNextPageNum);
        // 初始化当前页导航条的最后一页
        navigateLastPage = Math.min(pageNum +currentNextPageNum,lastPrevPage-1);

        /* 将所有计算出来的页码范围合并，并过滤掉不符合或多余的页码按钮 */
        Stream.of(currentPrevPageNums,currentNextPageNums)
                .flatMapToInt(intStream -> intStream)   // 定义流中流并将所有的字符串转为int
                .filter(e -> e>firstNextPage&&e<lastPrevPage)  // 越界筛选，筛选出规定范围内的页码按钮
                .distinct()                             // 去除重复的页码按钮
                .sorted()                               // 将筛选出来的页码按自然顺序排序
                .forEach(e -> navigatepageNums.add(e)); // 将排序好的页码依次放入到导航容器
        // 预览所有需要展示的导航按钮
        System.out.println("导航按钮："+ navigatepageNums);
    }
    /* 初始化分页参数 */
    private void pageinto(){
        prePage = Math.max(pageNum -1,1);        // 初始化上一页
        nextPage = Math.min(pageNum +1,pages);   // 初始化下一页
        firstNextPage = 1+firstNextNum;
        lastPrevPage = pages-lastPrevNum;

        /* 动态调整页码范围，使显示出来的页码按钮的数量始终保持不变 */
        // 如果当前页的导航条按钮数超过了当前页约定的第一页的极限范围则做以下调整
        if (pageNum -currentPrevPageNum <= firstNextPage+1){
            currentNextPageNum += firstNextPage-(pageNum -currentPrevPageNum)+1;
        }
        // 如果当前页的导航条按钮数超过了当前页约定的最后一页的极限范围则做以下调整
        if (pageNum +currentNextPageNum >= lastPrevPage-1){
            currentPrevPageNum += (pageNum +currentNextPageNum)-lastPrevPage+1;
        }
    }

    /* 有参构造 */
    public CustomPage(int pageNum, int pageSize) {
        this(pageNum,pageSize,100);
    }
    /* 有参构造 */
    public CustomPage(int pageNum, int pageSize, int total) {
        this(0,2,3,0, pageNum,pageSize,total);
    }
    /* 有参构造 */
    public CustomPage(
            int firstNextNum,
            int currentPrevPageNum,
            int currentNextPageNum,
            int lastPrevNum,
            int pageNum, int pageSize) {
        this(firstNextNum,currentPrevPageNum,currentNextPageNum,lastPrevNum, pageNum,pageSize,100);
    }
    /* 有参构造 */
    public CustomPage(
            int firstNextNum,
            int currentPrevPageNum,
            int currentNextPageNum,
            int lastPrevNum,
            int pageNum, int pageSize, int total) {
        this.firstNextNum = firstNextNum;
        this.currentPrevPageNum = currentPrevPageNum;
        this.currentNextPageNum = currentNextPageNum;
        this.lastPrevNum = lastPrevNum;
        this.total = total;
        this.pageSize = pageSize;
        pages = (int) Math.ceil(total*1.0/pageSize);  // ceil()向上取整
        /* 优化当前页的范围，保证当前页始终在（1-总页数）之间 */
        if (pageNum <1){
            pageNum = 1;
        }else if (pageNum > pages){
            pageNum = pages;
        }
        this.pageNum = pageNum;
        pageinto();
        createNavigatepageNums();
    }

    public List<Integer> getFirstNavigatepageNums() {
        return firstNavigatepageNums;
    }

    public List<Integer> getLastNavigatepageNums() {
        return lastNavigatepageNums;
    }

    public void setList(List<T> list) {
        this.list = list;
    }

    public List<Integer> getNavigatepageNums() {
        return navigatepageNums;
    }

    public int getNavigateFirstPage() {
        return navigateFirstPage;
    }

    public int getNavigateLastPage() {
        return navigateLastPage;
    }

    public int getTotal() {
        return total;
    }

    public int getPageSize() {
        return pageSize;
    }

    public int getPageNum() {
        return pageNum;
    }

    public int getPages() {
        return pages;
    }

    public int getCurrentPrevPageNum() {
        return currentPrevPageNum;
    }

    public int getCurrentNextPageNum() {
        return currentNextPageNum;
    }

    public int getPrePage() {
        return prePage;
    }

    public int getNextPage() {
        return nextPage;
    }

    public List<T> getList() {
        return list;
    }

    public int getFirstNextNum() {
        return firstNextNum;
    }

    public int getFirstNextPage() {
        return firstNextPage;
    }

    public int getLastPrevNum() {
        return lastPrevNum;
    }

    public int getLastPrevPage() {
        return lastPrevPage;
    }

    @Override
    public String toString() {
        return "CustomPage{" +
                "navigatepageNums=" + navigatepageNums +
                ", navigateFirstPage=" + navigateFirstPage +
                ", navigateLastPage=" + navigateLastPage +
                ", total=" + total +
                ", pageSize=" + pageSize +
                ", pageNum=" + pageNum +
                ", pages=" + pages +
                ", currentPrevPage=" + currentPrevPageNum +
                ", currentNextPage=" + currentNextPageNum +
                ", prePage=" + prePage +
                ", nextPage=" + nextPage +
                ", list=" + list +
                ", firstNextNum=" + firstNextNum +
                ", firstNextPage=" + firstNextPage +
                ", lastPrevNum=" + lastPrevNum +
                ", lastPrevPage=" + lastPrevPage +
                '}';
    }
}
